# -*- coding: utf-8 -*-
import traceback
import os
import base64
from odoo import http
from odoo.http import request, content_disposition
from odoo.exceptions import UserError, ValidationError
from odoo.tools import config
from odoo import models
from odoo.http import Response
from urllib.parse import urljoin
import json
import requests
import logging
from datetime import datetime, timedelta
from ronglian_sms_sdk import SmsSDK

_logger = logging.getLogger(__name__)
BASE_CONFIG = config.misc.get("wx_app", {})
APP_ID = BASE_CONFIG.get("appid")
SECRET = BASE_CONFIG.get("secret")
FILE_WHITE_lIST = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.xls', '.xlsx', '.csv', '.ods', '.pdf','.txt', '.doc', '.docx', '.rtf', '.md', '.pdf', '.odt', '.wps','.xlsm','.ppt', '.pptx', '.pps', '.ppsx', '.odp', '.key'];

def generate_access_token():  # 小程序端已被腾讯加密访问链接
    # 生成16位的uuid
    import uuid
    access_token = str(uuid.uuid1()).replace('-', '')
    return access_token

def check_user_login(code):
    data = ""
    params = {
        'appid': APP_ID,
        'secret': SECRET,
        'js_code': code,
        'grant_type': 'authorization_code'
    }
    resp = requests.get('https://api.weixin.qq.com/sns/jscode2session', params=params, timeout=2)
    _logger.warning(f'验证结果{resp.content.decode()}')
    if not code:
        data = {"msg":'缺失Code必要参数!','status': 601}

    elif not all([APP_ID,SECRET]):
        data = {"msg": f'缺失APP必要参数! -- APP_ID:{APP_ID}, SECRET:{SECRET}','status':602}

    # elif not eval(resp.content.decode()).get('openid') or not eval(resp.content.decode()).get('unionid'):
    elif not eval(resp.content.decode()).get('openid'):
        # data = {"msg": f"用户认证错误! -- open_id:{eval(resp.content.decode()).get('openid')}--user_id:{eval(resp.content.decode()).get('unionid')}",'status':603}
        data = {"msg": f"用户认证错误! -- open_id:{eval(resp.content.decode()).get('openid')}", 'status':603}
    return data, resp



class ComplexEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(obj, datetime.date):
            return obj.strftime('%Y-%m-%d')
        elif issubclass(type(obj), models.Model):
            return obj.id
        elif issubclass(type(obj), bytes):
            return {
                "type": "bytes",
                "value": obj.decode('utf-8')
            }
        else:
            return json.JSONEncoder.default(self, obj)



class FactoryVisitor(http.Controller):
    def get_wechat_user_uid(self, code):
        params = {
            'appid': APP_ID,
            'secret': SECRET,
            'js_code': code,
            'grant_type': 'authorization_code'
        }
        resp = requests.get('https://api.weixin.qq.com/sns/jscode2session', params=params, timeout=2)
        _logger.warning(f'响应结果{resp}')
        user_id = eval(resp.content.decode()).get('unionid')
        open_id = eval(resp.content.decode()).get('openid')
        return {
            "open_id": open_id,
            "user_id": user_id
        }


    def _user_login(self,resp):
        user_id = eval(resp.content.decode()).get('unionid')
        open_id = eval(resp.content.decode()).get('openid')
        obj = request.env['res.users'].sudo().search([("wx_user_id",'=',user_id), ("wx_open_id", '=', open_id)], limit=1)
        return obj
    @http.route('/factory/user_login', auth='public', method=['POST'], type='json', csrf=False)
    def user_login(self):
        code = request.jsonrequest.get("code")
        data, resp = check_user_login(code)
        current = datetime.now() + timedelta(hours=8)
        choose_start_time = current.strftime('%Y-%m-%d %H:%M')
        # _logger.warning(f"获取到当前时间{current.strftime('%Y-%m-%d %H:%M')}")
        if data:
            return data
        obj = self._user_login(resp)
        if not len(obj):
            return {
                "code": 403,
                "msg": f"用户不存在",
                "choose_start_time":choose_start_time
            }
        data = {
            "code": 200,
            "msg": "用户登陆认证成功",
            'user_name': obj.login,
            "choose_start_time":choose_start_time
        }
        login = obj.login
        uid = request.session.factory_authenticate(request.session.db, login, 'XXXX')
        request.params['login_success'] = True
        # return request.make_response(json.dumps(data, cls=ComplexEncoder),
        #                              headers=[("Access-Control-Allow-Origin", "*"),
        #                                       ("Content-Type", "application/json; charset=utf-8")])
        return data
    @http.route('/factory/upload_files', auth='user', method=['POST'], csrf=False)
    def get_user_upload_files(self):
        file_name = request.params.get('file_name')
        file = request.params.get('file')
        visitor_id = request.params.get('visitor_id')

        if file_name and '.' + file_name.split('.')[-1].lower() not in FILE_WHITE_lIST:
            data = {"data": f"附件上传失败仅允许上传图片/电子表格/pdf"}
            return request.make_response(json.dumps(data, cls=ComplexEncoder))

        # 读取文件内容
        file_content = file.read()

        Attachment = request.env['ir.attachment']
        attachment_values = {
            'name': file_name,
            'db_datas': file_content,
            'res_model': 'factory.visitor',  # 如果文件与某个模型关联
            'res_id': int(visitor_id),  # 如果文件与某个模型实例关联
            'type':'binary',
            'access_token': generate_access_token()
        }
        attachment_id = Attachment.sudo().create(attachment_values)
        visitor_obj = request.env['factory.visitor'].search([('id', '=', visitor_id)])
        visitor_obj.user_attachment_ids += attachment_id
        data = {"data": f"附件上传成功-{attachment_id}"}
        return request.make_response(json.dumps(data, cls=ComplexEncoder))

    @http.route('/factory/git_user_attachments_link', auth='user', method=['GET'])
    def git_user_attachments_link(self):
        visitor_id = request.params.get('visitor_id')
        params = request.env['ir.config_parameter'].sudo()
        server_url = params.get_param('web.user_attachment_url')
        attachment_link_list = []
        visitor_obj = request.env['factory.visitor'].sudo().search([('id', '=', visitor_id)])
        if len(visitor_obj) and len(visitor_obj.user_attachment_ids):
            attachment_link_list = [{'visitor_id': visitor_id, 'url': urljoin(server_url, i.local_url), "filename":i.name, 'access_token':i.access_token} for i in visitor_obj.user_attachment_ids]
        return request.make_response(json.dumps(attachment_link_list, cls=ComplexEncoder))

    @http.route('/factory/approval', type="json", auth='user', method=['POST'])
    def approval(self):
        order_id = request.jsonrequest.get("order_id")
        state = request.jsonrequest.get("state")
        code = request.jsonrequest.get("code")
        approved_reject_reason = request.jsonrequest.get("approved_reject_reason")
        data, resp = check_user_login(code)
        if data:
            return data
        user_obj = self._user_login(resp)
        if request.env.user.id != user_obj.id:
            raise ValidationError(f'没有权限审批订单order-{order_id}')
        """
        state   
        agree  同意
        reject  拒绝
        """
        obj = request.env['factory.visitor'].browse(order_id)
        if len(obj):
            if state == "agree":
                obj.approve(remark='已审批', result=True)
            elif state == "reject":
                obj.approve(remark='已拒绝', result=False, reject_reason=approved_reject_reason)
            else:
                raise ValidationError(f"Invalid state [{state}]")
            data = {"msg": "审批成功!"}
            return data
        else:
            raise ValidationError(f'审批订单不存在 order-{order_id}')

    @http.route('/factory/get_qr_code', auth='public', method=['GET'])
    def get_qr_code(self):
        # fixme 需要加审批人身份
        # request.session.authenticate(request.session.db, "admin", 'admin')
        order_id = request.params.get("order_id")
        obj = request.env['factory.visitor'].browse(order_id)
        if len(obj):
            data = {"qr_code_url":  obj.get_qr_code_url()}
            return request.make_response(json.dumps(data, cls=ComplexEncoder))
        else:
            error_message = f'审批订单不存在 order-{order_id}'
            return Response(error_message, status=500)

    @http.route('/test/login', auth='public', method=['GET'])
    def get_qr_code_login(self):
        uid = request.session.authenticate(request.session.db, "admin", 'admin')
        request.params['login_success'] = True
        redirect = '/web#id=13&action=230&model=factory.visitor&view_type=form&cids=1&menu_id=199'
        return http.redirect_with_hash(self._login_redirect(uid, redirect=redirect))
    def conversion_datetime(self, date):
        if not date:
            return
        # new_date = date + timedelta(hours=8)
        return date.strftime("%Y-%m-%d %H:%M")

    def get_approval_data(self, obj):
        result = {}
        current_node = 0
        if len(obj.factory_approval_log_ids):
            approval_data = []
            for i in obj.factory_approval_log_ids:
                approval_dict = {
                    'approval_name': i.approval_user.name,
                    'approval_state': '已审批' if i.result else '审批中',
                    'approval_icon': "user-checked" if i.result else 'user-unknown',
                    'approval_sequence': 1 if i.result else 0,
                }
                if i.is_reject:
                    approval_dict['approval_icon'] = 'user-clear'
                    approval_dict['approval_state'] = '已拒绝'
                approval_data.append(approval_dict)
                if i.result:
                    current_node += 1
            approval_data.sort(key=lambda i: i['approval_sequence'], reverse=True)
            approval_data.append({'approval_state': '审批完成', 'approval_icon': 'assignment-checked'})

            if current_node == len(obj.factory_approval_log_ids):
                current_node += 1  # 审批完成
            result = {
                "current_node":current_node,
                "approval_data":approval_data
            }
        return result

    @http.route('/factory/visitor_submit_list', type="json", auth='user', method=['POST'], csrf=False)
    def visitor_submit_list(self):
        try:
            visitor_obj = request.env["factory.visitor"].sudo()
            visitor_submit_list = visitor_obj.search([('create_uid', '=', request.env.user.id), ('state', 'not in', ["draft"])], order="create_date desc")
            res = []
            attachment_link_list = []
            # 分页
            result = request.env["factory.visitor"].sudo().build_current_page_objs(order_objs=visitor_submit_list, page_start=request.jsonrequest.get('page_start'))
            visitor_activeValues = []   # 前端默认展示列表
            for i in result[0]['order_data']:
                is_show_qr_code_button = False
                if i.state in ["approved", 'enter_factory']:
                    is_show_qr_code_button = True
                res.append({
                    "id": i.id,
                    "workflow": i.workflow,
                    "state": self.transition_state_color(i.state).get('state'),
                    "create_date":self.conversion_datetime(i.create_date+timedelta(hours=8)),
                    "is_show_qr_code_button": is_show_qr_code_button,
                    "visitor_date": self.conversion_datetime(i.expected_visit_date+timedelta(hours=8)),
                    "color": self.transition_state_color(i.state).get('color'),
                    "reason_for_visit": i.reason_for_visit,
                    "visitor_name": i.visitor_name,
                    "visitor_phone": i.visitor_phone,
                    "visitor_unit": i.visitor_unit,
                    "number_of_visitor": i.number_of_visitor,
                    "reason_for_type": i.reason_for_type,
                    "delivery_car_number": i.delivery_car_number,
                    "delivery_boards_number": i.delivery_boards_number,
                    "delivery_volume": i.delivery_volume,
                    "visitor_item_list": i.visitor_item_list,
                    "respondent_or_consignee": i.respondent_or_consignee,
                    "leave_factory_date": self.conversion_datetime(i.leave_factory_date+timedelta(hours=8) if i.leave_factory_date else i.leave_factory_date),
                    "actual_factory_date": self.conversion_datetime(i.actual_factory_date+timedelta(hours=8) if i.actual_factory_date else i.actual_factory_date),
                    "attachment_link_list": True if i.user_attachment_ids else False,
                    "detail_for_delivery": i.detail_for_delivery,
                    "respondent_ids": [{"visitor_name":i.name, "visitor_phone": i.login} for i in i.respondent_ids], # 被访人手机号是登陆账号
                    "approval_data":self.get_approval_data(i),
                    "respondent_address": i.respondent_address_id.name if i.respondent_address_id else None
                })
                visitor_activeValues.append(i.id)

            return {
                "visitor_submit_list": res,
                "visitor_activeValues": visitor_activeValues[:1],
                'page_total_number':result[0]['page_total_number']
            }
            return request.make_response(json.dumps(res,cls=ComplexEncoder))
        except:
            _logger.error('服务器错误' + traceback.format_exc())
            return {
                "visitor_submit_list": [],
            }

    def check_required_field(self, data):
        for k,v in data.items():
            if not v:
                raise ValidationError(f"{k} 是必填字段")

    @http.route('/factory/create_user_and_login', type="json", auth='none', method=['POST'])
    def create_user_and_login(self):
        try:
            params = request.jsonrequest
            group_obj = request.env['res.groups']
            _logger.warning(f'请求结果{params}')
            if not request.env.user:
                wechat_user_code = params.get("wechat_user_code")
                user_phone = params.get('user_phone', None)
                user_phone_code = params.get('user_phone_code', None)
                wecom_userid = params.get('wecom_userid', None)
                user_group = params.get('user_group', 'Visitor')
                respondent_name = params.get('respondent_name', 'Visitor')
                if not all([user_phone_code, user_phone]):
                    status_code = 501
                    msg = "缺少参数"
                    return {
                        "status": status_code,
                        "msg":msg
                    }
                else:
                     # 验证码验证
                     result = request.env['factory.visitor'].verify_verification_code(user_phone, user_phone_code)
                     if not result[0]:
                         status_code = 502
                         msg = result[1]
                         return {
                             "status": status_code,
                             "msg": msg
                         }
                # 创建用户
                wechat_data = self.get_wechat_user_uid(wechat_user_code)
                _logger.warning(f'登录返回结果{wechat_data}')
                user_obj = request.env["res.users"].sudo().search(['|', ("wx_open_id", "=", wechat_data['open_id']), ("login", "=", user_phone)])
                if len(user_obj):
                    msg = f'当前微信小程序客户端已被手机号为{user_obj.login[:4] + "****" + user_obj.login[-4:]}的用户注册，请勿重复注册'
                    raise ValidationError(msg)

                else:
                    group_obj = request.env['res.groups'].sudo().search([('name', '=', user_group)])
                    user = request.env["res.users"].with_user(2).create(
                        {
                            "login": user_phone,
                            "company_id": 1,
                            "company_ids": [1],
                            "name": respondent_name,
                            'email': f"{user_phone}"
                        }
                    )
                    if group_obj:
                        user.groups_id += group_obj
                    # 用当前用户登录
                    request.env.cr.commit()
                    user.wx_open_id = wechat_data['open_id']
                    user.wx_user_id = wechat_data['user_id']
                    user.wecom_userid = wecom_userid
                    uid = request.session.factory_authenticate(request.session.db, user.login, 'XXXX')
                    request.params['login_success'] = True
                    request.env.user = user
                    return {
                        'status': 200,
                        "visitor_id": user.id,
                        "visitor_name": request.env.user.login
                    }
        except Exception as e:
            _logger.error("服务器报错" + traceback.format_exc())
            return {
                'status': 501,
                "msg": e.args[0] if e else '服务器错误'
            }

    def _get_respondent_user(self, respondent_phone_number):
        user_obj = request.env['res.users'].sudo().search([('login', '=', respondent_phone_number)])
        return user_obj



    def check_file(self):
        ...
    @http.route('/factory/visitor_coding_submit', type="json", auth='user', method=['POST'], csrf=False)
    def visitor_coding_submit(self):
        try:
            params = request.jsonrequest
            # filter_has_upload_file_list = params.get('filter_has_upload_file_list', None)
            visitor_name = params.get('visitor_name', None)
            visitor_phone = params.get('visitor_phone', None)
            visitor_identity_card_number = params.get('visitor_identity_card_number', None)
            visitor_unit = params.get('visitor_unit', None)
            number_of_visitor = params.get('number_of_visitor', None)
            reason_for_visit = params.get('reason_for_visit', None)
            delivery_volume = params.get('delivery_volume', None)
            delivery_boards_number = params.get('delivery_boards_number', None)
            delivery_car_number = params.get('delivery_car_number', None)
            detail_for_delivery = params.get('detail_for_delivery', None)
            visitor_item_list = params.get('visitor_item_list', None)
            expected_visit_date = params.get('expected_visit_date', None)
            reason_for_type = params.get('reason_for_type', None)
            sms_log_id = params.get('sms_log_id', None)
            query_respondent_list = params.get('query_respondent_list', [])
            respondent_address_id = params.get('respondent_address_id')
            uuid = params.get('uuid')
            _logger.error(f'获取到前端的时间是{expected_visit_date}')
            if query_respondent_list:
                query_respondent_list = [i.get('value') for i in query_respondent_list]
            data = {
                "visitor_name":visitor_name,
                "uuid":uuid,
                "visitor_phone":visitor_phone,
                "visitor_identity_card_number":visitor_identity_card_number,
                "visitor_unit":visitor_unit,
                "number_of_visitor":number_of_visitor,
                "visitor_item_list":visitor_item_list,
                "delivery_boards_number":delivery_boards_number,
                "delivery_volume":delivery_volume,
                "expected_visit_date":expected_visit_date,
                "reason_for_type":reason_for_type,
                "detail_for_delivery":detail_for_delivery,
                "reason_for_visit":reason_for_visit,
                "delivery_car_number":delivery_car_number,
                "approver_ids": [(6, 0, query_respondent_list)],
                "respondent_ids": [(6, 0, query_respondent_list)],
                "respondent_address_id": respondent_address_id[1] if respondent_address_id else None,
            }
            # FIXME self.check_required_field(data)
            visitor_order_obj = request.env['factory.visitor'].create(data)
            visitor_order_obj.expected_visit_date = visitor_order_obj.expected_visit_date-timedelta(hours=8)
            _logger.error(f'后端转换后时间是{visitor_order_obj.expected_visit_date }')
            # visitor_order_obj.respondent_qw_wechat_number = request.env['res.users'].sudo().browse(query_respondent_list).wecom_userid
            if sms_log_id:
                visitor_order_obj.factory_log_ids = [(6, 0, [sms_log_id])]

            attachment_objs = request.env['ir.attachment'].sudo().search([('uuid', '=', uuid)])
            for i in attachment_objs:
                i.res_id = visitor_order_obj.id
                visitor_order_obj.user_attachment_ids += i
            visitor_order_obj.submmit()
            visitor_order_obj.wechat_notify(description=f'供应商:{visitor_order_obj.visitor_name},已提交访客申请，请及时审批', remark='通知审批人审批')
            result = {
                "status": 200,
                "visitor_id": visitor_order_obj.id,
                "visitor_name": request.env.user.login
            }
            return result
        except:
            _logger.error("服务器报错" + traceback.format_exc())
    def transition_state_color(self, state=None):
        """
            approving: 审批中,"background-color":"#00BFFF",
            approved: 审批完成"background-color":"#4EEE94",
            reject: 审批拒绝,"background-color":"#FF3030",
            enter_factory: 已进厂,"background-color":"#BBFFFF",
            leave_factory: 已离场,"background-color":"#DCDCDC",
        """
        if state == 'approving':
            return {'state':"审批中", 'color':"#C0C0C0"}
        elif state == 'approved':
            return {'state':"审批通过", 'color':"#32CD32"}
        elif state == 'reject':
            return {'state':"审批拒绝", 'color':"#FF3030"}
        elif state == 'enter_factory':
            return {'state':"已进厂", 'color':"#1E90FF"}
        else:
            return {'state':"已离场", 'color':"#DCDCDC"}

    @http.route('/factory/approval_list', type="json", auth='user', method=['POST'])
    def visitor_approval_list(self):
        visitor_submit_list = request.env["factory.visitor"].sudo().search([('approver_ids', 'in', request.env.user.ids),
                                                                            ('state', 'in', ["approving"])
                                                                            ], order="create_date desc")
        res = []
        visitor_activeValues = []   # 前端默认展示列表
        result = request.env["factory.visitor"].sudo().build_current_page_objs(order_objs=visitor_submit_list,page_start=request.jsonrequest.get('page_start'))
        for i in result[0]['order_data']:
            is_show_approval_button = False
            if i.state == "approving":
                is_show_approval_button = True

            for j in i.factory_approval_log_ids:
                if j.approval_user.id == request.env.user.id and not j.result:
                    res.append({
                        "id": i.id,
                        "is_show_approval_button":is_show_approval_button,
                        "workflow": i.workflow,
                        "state": self.transition_state_color(i.state).get('state'),
                        "create_date": self.conversion_datetime(i.create_date+timedelta(hours=8)),
                        "visitor_date": self.conversion_datetime(i.expected_visit_date+timedelta(hours=8)),
                        "color": self.transition_state_color(i.state).get('color'),
                        "reason_for_visit": i.reason_for_visit,
                        "visitor_name": i.visitor_name,
                        "visitor_phone": i.visitor_phone,
                        "visitor_unit": i.visitor_unit,
                        "number_of_visitor": i.number_of_visitor,
                        "reason_for_type": i.reason_for_type,
                        "delivery_car_number": i.delivery_car_number,
                        "delivery_boards_number": i.delivery_boards_number,
                        "delivery_volume": i.delivery_volume,
                        "visitor_item_list": i.visitor_item_list,
                        "respondent_or_consignee": i.respondent_or_consignee,
                        "leave_factory_date": self.conversion_datetime(i.leave_factory_date+timedelta(hours=8) if i.leave_factory_date else i.leave_factory_date),
                        "actual_factory_date": self.conversion_datetime(i.actual_factory_date+timedelta(hours=8) if i.actual_factory_date else i.actual_factory_date),
                        "attachment_link_list": True if i.user_attachment_ids else False,
                        "detail_for_delivery": i.detail_for_delivery,
                        "respondent_ids": [{"visitor_name": i.name, "visitor_phone": i.login} for i in i.respondent_ids],
                        "respondent_address": i.respondent_address_id.name if i.respondent_address_id else None
                        # 被访人手机号是登陆账号
                    })
                    visitor_activeValues.append(i.id)

        return {
            "visitor_submit_list": res,
            "visitor_activeValues": visitor_activeValues[:1],
            'page_total_number': result[0]['page_total_number']
        }
        return request.make_response(json.dumps(res,cls=ComplexEncoder))

    def _login_redirect(self, uid, redirect=None):
        return _get_login_redirect_url(uid, redirect)


    @http.route('/factory/active_order', auth='user', type='json', method=['PUT'], csrf=False)
    def visitor_active_order(self):
        order_id = request.jsonrequest.get("order_id")
        order_obj = request.env['factory.visitor'].sudo().search([('create_uid', '=', request.env.user.id), ('id', '=', order_id)])
        if len(order_obj):
            order_obj.active = False
            return {
                'msg': '归档成功'
            }
        else:
            return {'msg': '无权限操作'}


    @http.route('/factory/send_phone_verify_code', type="json", auth='none', method=['POST'])
    def send_phone_verify_code(self):
        # FIXME  加入前端code校验
        params = request.jsonrequest
        wx_login_code = params.get('wx_login_code')
        phone_number = params.get('phone_number')
        sms_log_id = None
        if not all([wx_login_code,phone_number]):
            msg = '缺失手机号'
            status_code = 400
        else:
            send_result = request.env['factory.visitor'].sudo().sms_notify(phone_number=phone_number)
            msg = send_result[1]
            sms_log_id = send_result[2]
            if not send_result[0]:
                status_code = 500
            else:
                status_code = 200

        result = {
            'status_code': status_code,
            'msg': msg,
            "sms_log_id": sms_log_id
        }
        return result

    @http.route('/factory/submit_verify', type="json", auth='none', method=['POST'])
    def submit_verify(self):
        verify_dict = {
            'visitor_phone': {'status': 601, 'msg': '请填写访客电话号码'},
            'query_respondent_list': {'status': 602, 'msg': '请选择被访人'},
            'visitor_name': {'status': 603, 'msg': '请填写访客姓名'},
            'visitor_unit': {'status': 604, 'msg': '请填写访客单位'},
            'number_of_visitor': {'status': 605, 'msg': '请填写访客数量'},
            'reason_for_visit': {'status': 606, 'msg': '请填写访问原因'},
            'expected_visit_date': {'status': 607, 'msg': '请填写预计访问时间'},
            'respondent_address_id': {'status': 608, 'msg': '请选择被访人单位'},
            'visitor_identity_card_number': {'status': 609, 'msg': '请填写身份证号'},
        }

        params = request.jsonrequest

        for k, v in params.items():
            if k in verify_dict and not v:
                return {
                    'status': verify_dict[k]['status'],
                    'msg': verify_dict[k]['msg']
                }
        else:
            return {
                'status': 200,
                'msg': '验证通过'
            }


    @http.route('/factory/search_respondent', auth='public', method=['GET'], type='http')
    def search_respondent(self):
        try:
            user_obj_list = []
            # 验证是否是从微信端加载过来的，防止爬虫直接调用
            code = request.params.get("code")
            data, resp = check_user_login(code)
            if data:
                return json.dumps(data)
            # 获取搜索框内容
            search_content = request.params.get("search_content")
            search_unit = request.params.get("search_unit")
            if search_content:
                user_objs = self._search_respondent(search_content, search_unit)
                user_obj_list = self._build_user_objs_data(user_obj_list,user_objs)
            return json.dumps({
                'status': 200,
                'msg': '查询成功',
                'data': user_obj_list
            })
        except Exception as e:
            _logger.error(f'查询失败{e}')
            return json.dumps({
                'status': 604,
                'msg': f'查询失败{e}',
                'data': []
            })

    @http.route('/factory/query_respondent', auth='public', method=['GET'], type='http')
    def query_respondent(self):
        try:
            user_obj_list = []
            # 验证是否是从微信端加载过来的，防止爬虫直接调用
            code = request.params.get("code")
            data, resp = check_user_login(code)
            if data:
                return json.dumps(data)
            # 获取搜索框内容
            query_respondent_list = request.params.get("query_respondent_list")
            if query_respondent_list:
                query_respondent_list = json.loads(query_respondent_list)
                user_objs = self._query_respondent(query_respondent_list)
                user_obj_list = self._build_user_objs_data(user_obj_list, user_objs)
            return json.dumps({
                'status': 200,
                'msg': '查询成功',
                'data': user_obj_list
            })
        except Exception as e:
            _logger.error(f'查询失败{e}')
            return json.dumps({
                'status': 604,
                'msg': f'查询失败{e}',
                'data': []
            })

    def _query_respondent(self, query_respondent_list):
        user_objs = request.env['res.users'].sudo().search([('id', 'in', query_respondent_list)])
        return user_objs
    def _search_respondent(self, search_content, search_unit):
        user_objs = request.env['res.users']
        # user_group = request.env['res.groups'].sudo().search([('name', '=', "Respondent")])
        if not search_content or search_content  == 'null':
            respondent_message_record = request.env['respondent.message'].sudo().search([('respondent_address_id', '=', eval(search_unit)[1])])
            for i in respondent_message_record:
                user_objs += i.user_id
        else:
            split_symbol = [',', '，'] # 中英文逗号分隔
            for i in split_symbol:
                if i in search_content:
                    search_content = search_content.replace(i, ',')
            search_content_list = search_content.split(',')
            for i in search_content_list:
                if i:
                    domain = ['|', ('login', 'ilike', i), ('name', 'ilike', i)]
                    user_obj = request.env['res.users'].sudo().search(domain)
                    if len(user_obj):
                        respondent_domain = [('user_id', 'in', [i.id for i in user_obj])]
                        user_obj = request.env['respondent.message'].sudo().search(respondent_domain)
                        if len(user_obj) and len(eval(search_unit)):
                            if user_obj.respondent_address_id.id == eval(search_unit)[1]:
                                user_objs += user_obj.user_id
                        # for i in user_obj:
                        #     if user_group in i.groups_id:
                        #         user_objs += i

        # 对结果去重，防止列表中的元素模糊匹配重复
        user_objs = list(set(list(user_objs)))
        return user_objs
    def _build_user_objs_data(self, user_obj_list,user_objs):
        for i in user_objs:
            # 根据前端组件的数据结构 定义的key
            user_data = {
                'label': i.sudo().login,
                'content': i.sudo().name,
                'value': i.sudo().id,
            }
            user_obj_list.append(user_data)
        return user_obj_list

    @http.route('/factory/search_respondent_address', auth='public', method=['GET'], type='http')
    def search_respondent_address(self):
        result = []
        current = datetime.now() + timedelta(hours=8)
        choose_start_time = current.strftime('%Y-%m-%d %H:%M')
        try:
            code = request.params.get("code")
            data, resp = check_user_login(code)
            if data:
                return data
            respondent_address_objs = request.env['respondent.address'].sudo().search([])
            result = [
                {'label': i.name, 'value': i.unit_name, 'id': i.id} for i in request.env['respondent.unit'].sudo().search([])]
            for i in result:
                for j in respondent_address_objs:
                    if j.respondent_unit_id.id == i.get('id'):
                        if i.get('address_list'):
                            i['address_list'].append({'label': j.address, 'value': j.id, 'default': j.default})
                        else:
                            i['address_list'] = [{'label': j.address, 'value': j.id, 'default': j.default}]
            result = self._clean_result(result)
        except Exception as e:
            result = []
            _logger.error(f'查询失败{e}')

        finally:
            return json.dumps({
                'status': 200,
                'result': result,
                "choose_start_time": choose_start_time
            })


    def _clean_result(self, result):
        for i in result:
            if i.get('address_list'):
                address_list = sorted(i['address_list'], key=lambda x: x['default'], reverse=True)
                i['address_list'] = address_list
        return result

def _get_login_redirect_url(uid, redirect=None):
    """ Decide if user requires a specific post-login redirect, e.g. for 2FA, or if they are
    fully logged and can proceed to the requested URL
    """
    import werkzeug
    import werkzeug.exceptions
    import werkzeug.utils
    import werkzeug.wrappers
    import werkzeug.wsgi
    from collections import OrderedDict, defaultdict, Counter
    from werkzeug.urls import url_encode, url_decode, iri_to_uri
    from lxml import etree
    import unicodedata
    if request.session.uid: # fully logged
        return redirect or '/web'

    # partial session (MFA)
    url = request.env(user=uid)['res.users'].browse(uid)._mfa_url()
    if not redirect:
        return url

    parsed = werkzeug.urls.url_parse(url)
    qs = parsed.decode_query()
    qs['redirect'] = redirect
    return parsed.replace(query=werkzeug.urls.url_encode(qs)).to_url()


class UploadController(http.Controller):
    @http.route('/upload/file', type='http', auth='public')
    def upload_page(self):
        file = 'upload_file.html'
        module_path = os.path.dirname(os.path.dirname(__file__))
        uuid = request.params.get('uuid')
        if not uuid:
            file = '404.html'
        _logger.error(f'获取到的UUID是{uuid}')
        # 获取HTML文件路径
        try:
            html_path = os.path.join(module_path, 'static', 'src', 'html', file)
            # 读取HTML文件内容
            with open(html_path, 'r', encoding='utf-8') as file:
                html_content = file.read()
                # 创建响应对象
                response = request.make_response(
                    html_content,
                    headers=[
                        ('Content-Type', 'text/html; charset=utf-8'),
                        ('Set-Cookie', f'uuid={uuid};'),
       ]
                )
                return response
        except Exception as e:
            # 出错时返回错误信息
            return f"Server Error: {str(e)}"

    @http.route('/get/upload_file', type='http', auth='public', methods=['POST'], csrf=False)
    def upload_file(self):
        try:
            uuid = request.params.get('uuid')
            if not uuid:
                raise ValidationError('客户端错误')
            # 获取上传的文件
            file = request.httprequest.files.get('file')
            if not file:
                raise ValidationError('未找到上传文件')
            # 获取文件名和内容
            file_name = file.filename
            if file_name:
                file_suffix = '.' + file_name.split('.')[-1]
                if file_suffix.lower() not in FILE_WHITE_lIST:
                    raise ValidationError('仅允许上传/图片/pdf/表格')
                else:
                    file_content = file.read()
                    # 将文件内容转换为Base64编码（Odoo中存储二进制数据的常用方式）
                    file_b64 = base64.b64encode(file_content).decode('utf-8')
                    # 创建附件记录（ir.attachment是Odoo中存储附件的标准模型）
                    attachment = request.env['ir.attachment'].sudo().create({
                        'name': file_name,
                        'datas': file_b64,
                        'res_model': 'factory.visitor',  # 可选：关联到特定模型
                        'res_id': 0,  # 可选：关联到特定记录ID
                        'access_token':generate_access_token(),
                        'uuid': uuid,
                    })
                    _logger.error(f'获取到的UUID是{uuid}')
                    _logger.error(f'获取到附件是{attachment.id}')
                    result = {
                        'id': attachment.id,
                        'name': attachment.name,
                        'size': attachment.file_size,
                        'path': attachment.local_url,
                        'has_upload': True,
                        'success': True,
                        'message': '文件上传成功',
                        'access_token': attachment.access_token
                    },
        except Exception as e:
            result = {
                'has_upload': False,
                'success': False,
                'message': f'上传失败: {str(e)}',
            },
        finally:
            return request.make_response(json.dumps(
                result
            ), headers=[('Content-Type', 'application/json')])


    @http.route('/query/uuid/attachments', type='http', auth='public')
    def query_attachment(self):
        uuid = request.params.get('uuid')
        code = request.params.get('code')
        if not uuid or not code:
            return json.dumps({'msg':'客户端异常'})
        data, resp = check_user_login(code)
        if data:
            return json.dumps(data)
        result = []

        attachments = request.env['ir.attachment'].sudo().search([('uuid', '=', uuid)])
        for attachment in attachments:
            result.append({
                'id': attachment.id,
                'name': attachment.name,
                'size': attachment.file_size,
                'path': attachment.local_url,
                'has_upload': True,
                'success': True,
                'message': '文件上传成功',
                'access_token': attachment.access_token
            }),
        return request.make_response(json.dumps(
            result
        ), headers=[('Content-Type', 'application/json')])




